#include "OssManger.h"
#include "Logger.h"

#include <alibabacloud/oss/OssClient.h>

using namespace AlibabaCloud::OSS;

namespace l
{

    //默认账户信息
    constexpr const char* OssManger_default_endpoint = "oss-cn-wuhan-lr.aliyuncs.com";
    constexpr const char* OssManger_default_region = "cn-wuhan";
    constexpr const char* OssManger_default_accessKeyId = "LTAI5tNDSioBpcvJ5aQ4XCzf";
    constexpr const char* OssManger_default_accessKeySercret = "Ylv316tVF6l2eX9rqJKG6kpELG4Qtp";
    constexpr const char* OssManger_default_bucketName = "cloulddisk";

    bool OssManger::upload_backup(const std::string& fileContent, const std::string& objectName)
    {

        /* 初始化网络等资源。*/
        InitializeSdk();

        /* 初始化OSS账号信息。*/
        std::string endpoint{ OssManger_default_endpoint };
        std::string region{ OssManger_default_region };
        std::string accessKeyId{ OssManger_default_accessKeyId };
        std::string accessKeySercret{ OssManger_default_accessKeySercret };

        ClientConfiguration conf{};
        OssClient client{ endpoint ,accessKeyId, accessKeySercret, conf };
        client.SetRegion(region);

        std::string bucketName{ OssManger_default_bucketName };

        std::shared_ptr<std::iostream> stream = std::make_shared<std::stringstream>(fileContent);

        PutObjectRequest request{ bucketName, objectName, stream };

        auto outcome = client.PutObject(request);

        if (!outcome.isSuccess()) {

            /* 异常处理。*/
            std::string err{ "PutObject fail " };
            err.append(",code:").append(outcome.error().Code())
                .append(",message:").append(outcome.error().Message())
                .append(",requestId:").append(outcome.error().RequestId()).append("\n");
            LogError(err);
#ifdef BUG
            std::cout << "PutObject fail" <<
                ",code:" << outcome.error().Code() <<
                ",message:" << outcome.error().Message() <<
                ",requestId:" << outcome.error().RequestId() << std::endl;
#endif

            ShutdownSdk();

            return false;

        }

        /* 释放网络等资源。*/
        ShutdownSdk();
        return true;
    }

    bool OssManger::upload_backup(std::string&& fileContent, std::string& objectName)
    {

        /* 初始化网络等资源。*/
        InitializeSdk();

        /* 初始化OSS账号信息。*/
        std::string endpoint{ OssManger_default_endpoint };
        std::string region{ OssManger_default_region };
        std::string accessKeyId{ OssManger_default_accessKeyId };
        std::string accessKeySercret{ OssManger_default_accessKeySercret };

        ClientConfiguration conf{};
        OssClient client{ endpoint ,accessKeyId, accessKeySercret, conf };
        client.SetRegion(region);

        std::string bucketName{ OssManger_default_bucketName };

        std::shared_ptr<std::iostream> stream = std::make_shared<std::stringstream>(std::move(fileContent));

        PutObjectRequest request{ bucketName, objectName, stream };

        auto outcome = client.PutObject(request);

        if (!outcome.isSuccess()) {

            /* 异常处理。*/
            std::string err{ "PutObject fail " };
            err.append(",code:").append(outcome.error().Code())
                .append(",message:").append(outcome.error().Message())
                .append(",requestId:").append(outcome.error().RequestId()).append("\n");

            LogError(err);
#ifdef BUG
            std::cout << "PutObject fail" <<
                ",code:" << outcome.error().Code() <<
                ",message:" << outcome.error().Message() <<
                ",requestId:" << outcome.error().RequestId() << std::endl;
#endif

            ShutdownSdk();

            return false;

        }

        /* 释放网络等资源。*/
        ShutdownSdk();
        return true;
    }


    bool OssManger::upload_backup_by_io(const std::string& fileName, const std::string& objectName) {

        /* 初始化网络等资源。*/
        InitializeSdk();

        /* 初始化OSS账号信息。*/
        std::string endpoint{ OssManger_default_endpoint };
        std::string region{ OssManger_default_region };
        std::string accessKeyId{ OssManger_default_accessKeyId };
        std::string accessKeySercret{ OssManger_default_accessKeySercret };

        ClientConfiguration conf{};
        OssClient client{ endpoint ,accessKeyId, accessKeySercret, conf };
        client.SetRegion(region);

        std::string bucketName{ OssManger_default_bucketName };

        auto outcome = client.PutObject(bucketName, objectName, fileName);

        if (!outcome.isSuccess()) {

            /* 异常处理。*/
            std::string err{ "PutObject fail " };
            err.append(",code:").append(outcome.error().Code())
                .append(",message:").append(outcome.error().Message())
                .append(",requestId:").append(outcome.error().RequestId()).append("\n");

            LogError(err);
#ifdef BUG
            std::cout << "PutObject fail" <<
                ",code:" << outcome.error().Code() <<
                ",message:" << outcome.error().Message() <<
                ",requestId:" << outcome.error().RequestId() << std::endl;
#endif

            ShutdownSdk();

            return false;

        }

        /* 释放网络等资源。*/
        ShutdownSdk();
        return true;


    }

}//end of namespace l